import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:people_big_people/utils/log_util.dart';

import '../utils/status_bar_color.dart';

var navKey = GlobalKey<NavigatorState>();

typedef LifecycleScopeCallback = void Function();

class LifecycleScope extends StatefulWidget {
  final Widget child;
  final LifecycleScopeCallback? onResumed;
  final LifecycleScopeCallback? onPaused;
  final StatusBarColor? statusBarColor;

  const LifecycleScope({
    Key? key,
    required this.child,
    this.onResumed,
    this.onPaused,
    this.statusBarColor,
  }) : super(key: key);

  @override
  State<StatefulWidget> createState() => _LifecycleScopeState();

// @override
// _LifecycleScopeState createState() => _LifecycleScopeState();
}

class _LifecycleScopeState extends State<LifecycleScope> with WidgetsBindingObserver {
  bool isInit = false;

  @override
  void initState() {
    super.initState();
    isInit = true;
    WidgetsBinding.instance.addObserver(this);
    LifecycleNavigatorObserver.instance._resumedCallbacks.add(navigatorResumed);
    LifecycleNavigatorObserver.instance._resumedCallbacks.add(navigatorPaused);
    WidgetsBinding.instance.addPostFrameCallback((timeStamp) {
      onResumed();
    });
    // Future.delayed(const Duration(milliseconds: 20)).then((v) {
    //   onResumed();
    // });
  }

  @override
  void dispose() {
    LifecycleNavigatorObserver.instance._resumedCallbacks.remove(navigatorResumed);
    LifecycleNavigatorObserver.instance._resumedCallbacks.remove(navigatorPaused);
    WidgetsBinding.instance.removeObserver(this);
    super.dispose();
  }

  @override
  void didChangeAppLifecycleState(AppLifecycleState state) {
    switch (state) {
      case AppLifecycleState.resumed:
        onResumed();
        break;
      case AppLifecycleState.paused:
        onPaused();
        break;
      case AppLifecycleState.inactive:
        break;
      case AppLifecycleState.detached:
        break;
    }
  }

  void navigatorResumed(Route<dynamic>? route) {
    if (ModalRoute.of(context) == route) onResumed();
  }

  void navigatorPaused(Route<dynamic>? route) {
    if (ModalRoute.of(context) == route) onPaused();
  }

  void onResumed() {
    if (!mounted) return;
    switch (widget.statusBarColor) {
      case StatusBarColor.dark:
        SystemChrome.setSystemUIOverlayStyle(dark);
        break;
      case StatusBarColor.light:
        SystemChrome.setSystemUIOverlayStyle(light);
        break;
      case null:
        break;
    }
    widget.onResumed?.call();
  }

  void onPaused() {
    if (!mounted) return;
    widget.onPaused?.call();
  }

  @override
  Widget build(BuildContext context) {
    return widget.child;
  }

  @override
  void didUpdateWidget(LifecycleScope oldWidget) {
    super.didUpdateWidget(oldWidget);
    LogUtil.i("LifecycleScope:resumed:${ModalRoute.of(context)?.settings.name},${widget.statusBarColor}");
    if (!mounted) return;
    if (oldWidget.statusBarColor != widget.statusBarColor) {
      switch (widget.statusBarColor) {
        case StatusBarColor.dark:
          SystemChrome.setSystemUIOverlayStyle(dark);
          break;
        case StatusBarColor.light:
          SystemChrome.setSystemUIOverlayStyle(light);
          break;
        case null:
          break;
      }
    }
  }

  @override
  void deactivate() {
    onPaused();
    super.deactivate();
  }

  @override
  void activate() {
    super.activate();
    onResumed();
  }
}

typedef _LifecycleNavigatorObserverCallback = void Function(Route<dynamic>? route);

class LifecycleNavigatorObserver extends NavigatorObserver {
  static final LifecycleNavigatorObserver instance = LifecycleNavigatorObserver._();

  LifecycleNavigatorObserver._();

  final List<_LifecycleNavigatorObserverCallback> _resumedCallbacks = [];
  final List<_LifecycleNavigatorObserverCallback> _pausedCallbacks = [];

  @override
  void didPush(Route<dynamic> route, Route<dynamic>? previousRoute) {
    super.didPush(route, previousRoute);
    LogUtil.i(route.toString());

    for (var cb in _resumedCallbacks) {
      cb(route);
    }
    for (var cb in _pausedCallbacks) {
      cb(previousRoute);
    }
  }

  @override
  void didPop(Route<dynamic> route, Route<dynamic>? previousRoute) {
    super.didPop(route, previousRoute);
    LogUtil.i(previousRoute?.settings.name);

    for (var cb in _pausedCallbacks) {
      cb(route);
    }
    for (var cb in _resumedCallbacks) {
      cb(previousRoute);
    }
  }


  @override
  void didReplace({Route<dynamic>? newRoute, Route<dynamic>? oldRoute}) {
    super.didReplace(newRoute: newRoute, oldRoute: oldRoute);
    for (var cb in _resumedCallbacks) {
      cb(newRoute);
    }
    for (var cb in _pausedCallbacks) {
      cb(oldRoute);
    }
  }
}
